/*
	This file is part of "Ants on the web".

    "Ants on the web" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "Ants on the web" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with "Ants on the web".  If not, see <http://www.gnu.org/licenses/>.
*/

package org.utc.ia04.antsontheweb.gui.request;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.UUID;

import org.utc.ia04.antsontheweb.antColonyOptimisation.antColony.AntColonyAgent;
import org.utc.ia04.antsontheweb.utilities.Requete;

import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.gui.GuiAgent;
import jade.gui.GuiEvent;
import jade.lang.acl.ACLMessage;
import jade.wrapper.AgentController;
import jade.wrapper.ContainerController;

public class AgentInterfaceRequest extends GuiAgent
{
	private static final long serialVersionUID = 1L;
	private PropertyChangeSupport changes;
	private boolean mainController;
	
	public static final String ANSWER = "AnswerFromACO";
	public static final int CREATE_AGENT = 0;
	public static final int SEND_TO_ACO = 1;
	
	//Df Information
	public static final String DF_TYPE = "InterfaceRequest";

	protected void setup()
	{
		//isMainController
		mainController = (Boolean)(getArguments()[0]);
		
		//Frame
		changes = new PropertyChangeSupport(this);
		new InterfaceRequest(this);
		
		//Behaviour
		addBehaviour(new AgentInterfaceRequestBhv());
		
		//Registration
		register();
	}
	
	public boolean isMainController()
	{
		return mainController;
	}
	
	private void register()
	{
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());
		ServiceDescription sd = new ServiceDescription();
		sd.setType(AgentInterfaceRequest.DF_TYPE); sd.setName(getName());
		dfd.addServices(sd);
		try { DFService.register(this, dfd); }
		catch (Exception fe) { System.out.println("Error during registration..."); }
	}
	
	public void sendAnswer(String answer)
	{
		changes.firePropertyChange(AgentInterfaceRequest.ANSWER, null, answer);
	}
	
	public void addPropertyChangeListener(PropertyChangeListener listener)
	{
		changes.addPropertyChangeListener(listener);
	}
	
	protected void onGuiEvent(GuiEvent arg0)
	{
		if(arg0.getType() == AgentInterfaceRequest.CREATE_AGENT)
			createAgent((String)arg0.getParameter(0), (String)arg0.getParameter(1), (Object[])arg0.getParameter(2));
		else if(arg0.getType() == AgentInterfaceRequest.SEND_TO_ACO)
			sendMessageToACO((Integer)arg0.getParameter(0), (String)arg0.getParameter(1));
	}
	
	private void createAgent(String nameType, String path, Object[] args)
	{
		try
		{
			ContainerController cc = getContainerController();
			UUID id = UUID.randomUUID();

			AgentController ac = cc.createNewAgent(nameType + id.toString(), path, args);
			ac.start();
		}
		catch(Exception e)
		{
			System.out.println("Error during agent creation : " + e.toString());
		}
	}
	
	private void sendMessageToACO(int codeRequete, String log)
	{
		//Requete
		Requete req = new Requete(codeRequete, log);
		ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
		message.setContent(req.serialize());
		
		//Receiver
		DFAgentDescription template = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();
		sd.setType(AntColonyAgent.dfType);
		template.addServices(sd);
		try
		{
			DFAgentDescription[] result = DFService.search(this, template);
			for(int i = 0; i < result.length; ++i)
				message.addReceiver(result[i].getName());
		}
		catch(Exception fe) {}
		
		//Envoie
		send(message);
	}
	
	public void takeDown()
	{
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());

		try { DFService.deregister(this, dfd); }
		catch (FIPAException e) { }
	}
}
